package com.llbnk.springcoding.thread;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.concurrent.LinkedBlockingQueue;


@Slf4j
public class ChangeCapacityBlockingQueue<T> extends LinkedBlockingQueue<T> {

    private volatile int length;

    public ChangeCapacityBlockingQueue(int capacity) {
        super(capacity);
        this.length = capacity;
    }

    public int getLength() {
        return length;
    }


    public boolean setCapacity(int capacity) {
        //1.校验capacity合法,capcity<=0或者小于当前队列长度
        if(capacity <= 0 || capacity < this.size()){
            return false;
        }
        //2.capcity和现在队列长度相等，则不处理
        if(capacity == this.size()){
            return true;
        }
        //3.通过反射获取父class的capacity，并通过反射赋值为最新的capacity
        /**
         * LinkedBlockingQueue --> private final int capacity;
         * 如果想改造需要改两点
         * 1.private
         * 2.final
         */
        try {
            Field capacityField = this.getClass().getSuperclass().getDeclaredField("capacity");
            //1.private
            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            //2.final 去掉方法 final & ~final
            modifiersField.setInt(capacityField,capacityField.getModifiers() & ~Modifier.FINAL);
            capacityField.setAccessible(true);

            //4.修改值
            capacityField.set(this,capacity);
        } catch (Exception e) {
            log.error("thread pool change capacity failed,old capacity:{},new capacity:{}",this.size(),capacity);
            return false;
        }
        return true;
    }

    public int getCapacity() {
        return getLength();
    }
}
